module test_mod;
use dbg_mod;
implicit none;

contains

logical function test_max_zero(z) result(res); implicit none;
  real(R14), intent(in) :: z;
  res = test_max_err(z, MAX_ZERO);
  return;
end function

logical function test_max_err(z, max_err) result(res); implicit none;
  real(R14), intent(in) :: z, max_err;
  res = (ABS(z) <= max_err);
  return;
end function

logical function test_max_diff(z, z2, max_err, trace_on) result(res); implicit none;
  real(R14), intent(in) :: z, z2, max_err;
  logical, optional, intent(in) :: trace_on;
  call dbg_real("test_max_diff(z=", z, trace_on);
  call dbg_real("____________(z2=", z2, trace_on);
  call dbg_real("_____(ABS(z-z2)=", ABS(z-z2), trace_on);
  call dbg_real("________max_err=", max_err, trace_on);
  res = (ABS(z-z2) <= max_err);
  return;
end function

subroutine assert_max_err(info, z, max_err); implicit none;
  character(LEN=*), intent(in) :: info;
  real(R14), intent(in) :: z, max_err;
  if (test_max_err(z, max_err)) return;
  call dbg_real(info, z);
  call dbg_real("exit assert_max_err=", max_err);
  call exit(1);
return;
end subroutine

subroutine assert_max_diff(info, z, z2, maxerr, trace); implicit none;
  character(LEN=*), intent(in) :: info;
  real(R14), intent(in) :: z, z2, maxerr;
  logical, optional, intent(in) :: trace;
  logical :: ok;
  call dbg_info(info, trace);
  ok = test_max_diff(z, z2, maxerr, trace);
  if (ok) return;
  call dbg_info(info, .TRUE.);
  ok = test_max_diff(z, z2, maxerr, .TRUE.); ! report error
  call exit(1);
return;
end subroutine


subroutine assert_max_diff_vec(info, pv, pv2, maxerr, trace);  implicit none;
  character(len=1024) :: helpi
  character(LEN=*), intent(in) :: info;
  real(R14), dimension(:), pointer :: pv, pv2;
  real(R14), intent(in) :: maxerr;
  logical, optional, intent(in) :: trace;
  integer :: i;
  do i = LBOUND(pv, 1), UBOUND(pv, 1)
    write (helpi, *) info, ", i = ", i;
    call assert_max_diff(TRIM(helpi), pv(i), pv2(i), maxerr, trace);
  end do
return;
end subroutine


subroutine assert_max_zero(info, z); implicit none;
  character(LEN=*), intent(in) :: info;
  real(R14), intent(in) :: z;
  call assert_max_err(info, z, MAX_ZERO);
return;
end subroutine


subroutine assert_true(info, ok); implicit none;
  character(LEN=*), intent(in) :: info;
  logical, intent(in) :: ok;
  if (ok) return;
  call dbg_bool(info, ok);
  call dbg_info("exit assert_true");
  call exit(1);
return;
end subroutine

subroutine assert_help_str(help, str); implicit none;
  character(LEN=*), intent(in) :: help, str;
  if (help == str) return;
  call dbg_str("help=", help);
  call dbg_str("str =", str);
  call dbg_info("exit in assert_help_str");
  call exit(1);
return;
end subroutine

end module
